package main

import "fmt"

func main() {
	/**
	接口：
		1. 一组方法的声明，且没有方法体。
		2. 子类必须重写接口中所有的函数，且函数名/入参/出参都保持一致
		3. 空接口表示所有类都属于它的子类，go语言内置一个类型为any的空接口
		4. 如果函数的入参使用了空接口，表示可以接收任意入参

	多态：
		1.使用父接口，可以接收任意类型的子类对象
		2.调用时只能调用父类已有的方法，子类新增的方法无法使用！
	*/
	var animal Animal
	animal = Cat{Name: "咪咪", Age: 2}
	// 只能调用接口的方法，子类的属性及其他方法无法使用
	animal.Eat()
	animal.Say()
	animal = Dog{Name: "大黄", Age: 3}
	animal.Eat()
	animal.Say()

	Test(1)
	Test('1')
	Test("1")
	Test(animal)
}

// Test go内置的空接口any
func Test(obj any) {
	fmt.Printf("入参类型：%T，值是%v\n", obj, obj)
}

type Animal interface {
	Eat()
	Say()
}

type Dog struct {
	Name string
	Age  int
}
type Cat struct {
	Name string
	Age  int
}

func (d Dog) Eat() {
	fmt.Println("狗吃肉")
}

func (d Dog) Say() {
	fmt.Println("汪汪汪")
}

func (d Dog) Work() {
	fmt.Println("看门")
}

func (c Cat) Eat() {
	fmt.Println("猫吃鱼")
}

func (c Cat) Say() {
	fmt.Println("喵喵喵")
}

func (c Cat) Work() {
	fmt.Println("抓老鼠")
}
